package academic.ui.client.widgets.forms;

import java.util.Date;


import ui.client.GenericContainerTag;
import ui.client.widgets.InputField;
import ui.client.widgets.PickListBox;

import academic.ui.client.jquery.JQuery;
import academic.ui.client.util.CardHelper;
import ecommerce.soco.shared.GWT_CreditCard;
import ecommerce.soco.shared.GWT_Order;
import ecommerce.soco.shared.GWT_Zone;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.i18n.client.NumberFormat;

public class AddEditCCForm extends FormWidget {

	private InputField ccName = new InputField("Card Holder's Name");
	private InputField ccNumber = new InputField("Credit Card Number");
	private InputField securityCode = new InputField("Security Code");
	private PickListBox expireMonth = new PickListBox();
	private PickListBox expireYear = new PickListBox();
	private InputField billingAddress = new InputField("Billing Address");
	private InputField city = new InputField("City");
	private PickListBox state = new PickListBox();
	private InputField zip = new InputField("Zip");
	
	private Boolean editMode = false;
	
	//labels
	private GenericContainerTag expireDateLbl = new GenericContainerTag("span","Expiration Date");
	private GenericContainerTag stateLbl = new GenericContainerTag("span", "State");
	
	public AddEditCCForm() {
		super();
		
		GenericContainerTag formFieldsDiv = new GenericContainerTag("div");
		formFieldsDiv.setStyleName("cc_form_fields");
		div.add(formFieldsDiv);
		GenericContainerTag float50 = new GenericContainerTag("div");
		float50.setStyleName("float50");
		float50.add(ccName);
		float50.add(ccNumber);
		float50.add(securityCode);
		securityCode.addStyleName("securityCode");
		GenericContainerTag expirationDateDiv = new GenericContainerTag("div");
		expirationDateDiv.setStyleName("expiration field");
		expirationDateDiv.add(expireDateLbl);
		expirationDateDiv.add(expireMonth);
		expirationDateDiv.add(expireYear);
		float50.add(expirationDateDiv);
		
		formFieldsDiv.add(float50);
		
		GenericContainerTag floatRight = new GenericContainerTag("div");
		floatRight.setStyleName("float50");
		
		floatRight.add(billingAddress);
		floatRight.add(city);
		GenericContainerTag stateAndZipDiv = new GenericContainerTag("div");
		stateAndZipDiv.setStyleName("state_and_zip");
		GenericContainerTag stateField = new GenericContainerTag("div");
		stateField.setStyleName("field");
		GenericContainerTag stateDiv = new GenericContainerTag("div");
		stateDiv.add(stateLbl);
		stateDiv.add(state);
		stateField.add(stateDiv);
		stateAndZipDiv.add(stateField);
		stateAndZipDiv.add(zip);
		
		floatRight.add(stateAndZipDiv);
		
		formFieldsDiv.add(floatRight);
		addMonthOptions();
		addYearOptions();
	}
	
	
	@Override
	public Boolean checkRules() {
		super.checkRules();
		if("".equals(billingAddress.getText()))
		{
			billingAddress.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","Billing Address is required."));
		}
		if("".equals(city.getText()))
		{
			city.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","City is required."));
		}
		if("".equals(state.getItemText(state.getSelectedIndex())))
		{
			state.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","State is required."));
		}
		if("".equals(zip.getText()))
		{
			zip.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","Zip is required."));
		}
		if("".equals(getExpirationDate()))
		{
			expireMonth.addStyleName("missingValue");
			expireYear.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","Expiration Date is required."));
		}
		if(isExpirationDateExpired())
		{
			expireMonth.addStyleName("missingValue");
			expireYear.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","Credit Card Expiration Date has passed."));
		}
		if("".equals(ccName.getText()))
		{
			ccName.addStyleName("missingValue");
			errorMsgs.add(new GenericContainerTag("div","Card Holder's Name is required"));
		}
		//These rules only apply when adding credit card
		if(!editMode)
		{
			if("".equals(ccNumber.getText()))
			{
				ccNumber.addStyleName("missingValue");
				errorMsgs.add(new GenericContainerTag("div","Credit Card Number is required"));
			}
			if(!CardHelper.validCC(ccNumber.getText()))
			{
				ccNumber.addStyleName("missingValue");
				errorMsgs.add(new GenericContainerTag("div","Credit Card Number is invalid"));
			}
		}
		return errorMsgs.getWidgetCount()<1;
	}
	
	protected String getExpirationDate() {
		return NumberFormat.getFormat("##00").format(Integer.parseInt(expireMonth.getItemText(expireMonth.getSelectedIndex()))) + expireYear.getItemText(expireYear.getSelectedIndex()).substring(2, 4);
	}
	
	protected Boolean  isExpirationDateExpired() {
		return (1900+new Date().getYear()) > Integer.parseInt(expireYear.getSelectedText()) ||
		((1900+new Date().getYear()) == Integer.parseInt(expireYear.getSelectedText()) && (new Date().getMonth()+1)>Integer.parseInt(expireMonth.getSelectedText()));
	}
	
	
	private void addMonthOptions() {
		expireMonth.clear();
		for (int i = 0; i < 12; i++) {
			expireMonth.addItem(String.valueOf(i + 1));
		}
	}

	private void addYearOptions() {
		expireYear.clear();
		for (int i = 0; i < 10; i++) {
			Date d = new Date();
			expireYear.addItem(String.valueOf(i + 1900 + d.getYear()));
		}

	}
	
	public void setCCNumber(String number) {
		ccNumber.setText(number);
	}
	
	public void setCCOwner(String ccOwner) {
		ccName.setText(ccOwner);
	}

	public void setExpireMonth(String ccExpires) {
		
	}


	public void setExpireDate(String ccExpires) {
		expireMonth.setSelectedIndex(Integer.parseInt(ccExpires.substring(0, 2)) - 1);	
		expireYear.setSelectedIndex(Integer.parseInt(ccExpires.substring(2, 4)) - 10);
		
	}


	public void setAddress(String billingAddress2) {
		billingAddress.setText(billingAddress2);
	}


	public void setCity(String billingCity) {
		city.setText(billingCity);
	}


	public void setState(String billingState) {
		state.setItemSelected(billingState);
	}


	public void setZip(String billingZip) {
		zip.setText(billingZip);
	}

	

	public GWT_CreditCard getCard(Integer id) {
		GWT_CreditCard card = new GWT_CreditCard();
		card.setCreditCardId(id);
		card.setBillingAddress(billingAddress.getText());
		card.setBillingCity(city.getText());
		card.setBillingState(state.getItemText(state.getSelectedIndex()));
		card.setBillingZip(zip.getText());
		card.setCcCVV(securityCode.getText());
		card.setCcExpires(getExpirationDate());
		card.setCcOwner(ccName.getText());
		if(!"".equals(ccNumber.getText()))
		{
			card.setCcNumber(ccNumber.getText());
			if(!editMode)
				card.setCcType(CardHelper.getCardName(CardHelper.getCardID(card.getCcNumber())));
		}
		
		return card;
	}
	
	
	public GWT_Order updateOrder(GWT_Order order) {
		order.customerName = ccName.getText();
		
		order.customerCity = city.getText();
		order.customerState = "Texas";
		order.customerCountry = "United States";
		order.customerPostcode = zip.getText();
		order.customerTelephone = "N";
		order.deliveryName = ccName.getText();
		order.deliveryCity = city.getText();
		order.deliveryCountry = "United States";
		order.deliveryStreetAddress = billingAddress.getText();
		order.deliveryPostcode = zip.getText();
		
		order.billingName = ccName.getText();
		order.billingStreetAddress = billingAddress.getText();
		
		order.billingCity = city.getText();
		order.billingPostcode = zip.getText();
		order.ccNumber = ccNumber.getText();
		order.ccOwner = order.billingName;
		order.customerStreetAddress = billingAddress.getText();
		order.paymentMethod = "0";
		order.setBillingCountry("United States");
		order.setCcCVV(securityCode.getText());
		order.setCcExpires(getExpirationDateString());
		order.getPaymentDetails().setCcCVV(securityCode.getText());
		order.getPaymentDetails().setCcExpiryMonth(
				expireMonth.getItemText(expireMonth.getSelectedIndex()));
		order.getPaymentDetails().setCcExpiryYear(
				expireYear.getItemText(expireYear.getSelectedIndex()));
		order.getPaymentDetails().setCcNumber(ccNumber.getText());
		order.getPaymentDetails().setCcOwner(ccName.getText());
		order.getPaymentDetails().setCcPostcode(zip.getText());
		order.getPaymentDetails().setCcStreetAddress(billingAddress.getText());

		return order;
	}
	
	private String getExpirationDateString() {
		Double expMonth = Double.parseDouble(expireMonth
				.getItemText(expireMonth.getSelectedIndex()));
		String expYear = expireYear.getItemText(expireYear.getSelectedIndex());
		NumberFormat nf = NumberFormat.getFormat("##");

		return nf.format(expMonth) + expYear.substring(2);
	}

	public void setStateOptions(GWT_Zone[] zones) {
		state.clear();
		for (GWT_Zone zone : zones)
			state.addItem(zone.zoneName);
		state.setItemSelected("Texas");
	}


	public void updateCard(GWT_CreditCard card) {		
		billingAddress.setText(card.getBillingAddress());
		city.setText(card.getBillingCity());
		state.setItemSelected(card.getBillingState());
		zip.setText(card.getBillingZip());
		securityCode.setText(card.getCcCVV());
		ccName.setText(card.getCcOwner());
		setExpireDate(card.getCcExpires());
		ccNumber.setText(card.getCcNumber());
	}
	
	public void disableCCNumber() {
		ccNumber.getField().setStyleName("disabledCC");
		ccNumber.getField().setEnabled(false);
	}


	public void enableCCNumber() {
		ccNumber.getField().removeStyleName("disabledCC");
		ccNumber.getField().setEnabled(true);
	}


	public void clearCard() {
		billingAddress.setText("");
		city.setText("");
		state.setItemSelected("Texas");
		zip.setText("");
		securityCode.setText("");
		ccName.setText("");
		setExpireDate("0111");
		ccNumber.setText("");
		removeErrors();
	}
	
	public Boolean isEditMode() {
		return editMode;
	}
	
	@Override
	public void removeErrors() {
		JQuery.hideAllErrors();
	}
	public void editMode(Boolean editMode) {
		this.editMode=editMode;
	}
}
